package com.kele.target22;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @author chunhui.li
 * @date 2022/2/8 14:28
 * @Description 反射机制的练习
 * @ClassName ReflectTest
 */
public class ReflectTest {

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        // 反射获得对象
        Class<Person> personClass = Person.class;
        // 获得所有的构造函数包括父类的（只能获得公共的）
        /**
         * 这里在反射获取所有构造器的时候有一点他的无参构造必须是共有的
         */
        Constructor<?>[] constructors = personClass.getConstructors();
        Arrays.stream(constructors).forEach(System.out::println);
        System.out.println("========================================");
        // 获得本类所有的构造函数包括私有的
        Constructor<?>[] declaredConstructors = personClass.getDeclaredConstructors();
        Arrays.stream(declaredConstructors).forEach(System.out::println);
        System.out.println("===================测试冲突1213=====================");
        // 获得本类所有的参数类型
        Field[] declaredFields = personClass.getDeclaredFields();
        Arrays.stream(declaredFields).forEach(System.out::println);
        // 操作有参构造构造函数
        /**
         * 有参构造函数里面参数类型为对应的参数类型
         */
        Constructor<Person> declaredConstructor = personClass.getDeclaredConstructor(String.class,Integer.class);
        // 因为有参构造是私有的所以使用暴力反射
        declaredConstructor.setAccessible(true);
        // 使用反射创建对象
        Person person = declaredConstructor.newInstance("kele", 23);
        System.out.println(person);
        System.out.println("========================================");
        // 反射操作方法
        //获得本类私有的方法
        Method declaredMethod = personClass.getDeclaredMethod("getPserson",null);
        declaredMethod.setAccessible(true);
        Object invoke = declaredMethod.invoke(person);
        System.out.println(invoke);
        System.out.println("========================================");
        // 反射操作本类的公有方法
        Constructor<Person> personConstructor= personClass.getDeclaredConstructor(null);
        Person person1 = personConstructor.newInstance();
        Method setPerson = personClass.getMethod("setPerson", String.class, Integer.class);
        Object hhhh = setPerson.invoke(person1, "hhhh", 12);
        System.out.println(hhhh);
        System.out.println("========================================");
        // 操作属性值
        Constructor<Person> declaredConstructor1 = personClass.getDeclaredConstructor();
        Person person2 = declaredConstructor1.newInstance();
        Field[] declaredFields1 = personClass.getDeclaredFields();
        Field name = personClass.getDeclaredField("name");
        name.setAccessible(true);
        name.set(person2,"xixixix");
        System.out.println(name.get(person2));
        System.out.println("========================================");
    }
}
